import random, sys, pygame, os #@UnresolvedImport

'''
    A GameGrid object tracks the state of all objects in the game space
    and relays this information to the nanobots, as well as controlling
    all GUI information.S
'''
class GameGrid():
    pygame.init()
    Clock = pygame.time.Clock()    

    size = width, height = 500, 500
    objects = []
    sprites = []
    screen = None
    backgroundcolor = (255,255,255)
    velocity = 25                   # Sets movement per iteration in terms of pixels
                                    # This can also be thought of as the step size
    framerate = 20                   # Max FPS

    # Constructor for GameGrid, creates blank lists of objects and sprites,
    # and creates the gui screen
    def __init__(self): 
        self.screen = pygame.display.set_mode(self.size)
        self.objects = []
        self.sprites = []        
    
    # Begins the system by starting a loop that will move the bots and
    # update the gui once per timestep
    def begin(self,goals):
        for robot in self.sprites:
            self.screen.blit(robot.image,robot.rect)    
        while 1:
            self.Clock.tick(self.framerate)
            for event in pygame.event.get():
                if event.type == pygame.QUIT: sys.exit()
            self.sprites = self.moveSprites(self.sprites,self.objects,goals)           
            self.updateScreen(self.screen)
    
    # Adds an object to the gui and grid
    def addObj(self, location, thing):
        self.objects.append(thing)
 
    # Checks to see if a given location has an object in it
    def checkLoc(self, location):
        for obj in self.objects:
            if obj.location == location:
                return obj
        return None

    # Returns the object at a given Location
    def getLoc(self, object):
        for obj in self.objects:
            if obj == object.location:
                return obj
        return None ## throw error?
    
    # Removes an object to the gui and grid
    def remove(self, object):
        self.objects.remove(object)
    
    # Returns a list of all objects within range of a location
    def checkRadius(self, location, range):
        objs = []
        for i in range(1, range+1):
            for j in range(1, range+1-i):
                for (a,b) in ((1,1 ),(1,-1 ),(-1,-1 ),(-1,1 )):
                    content = self.checkLoc((a*i,b*j))
                    if content is not None:
                        objs.append(content)

    # Updates the gui to reflect the positions of all elements
    def updateScreen(self, screen):
        screen.fill(self.backgroundcolor)
        for obj in self.objects:
            screen.blit(obj.image, obj.rect)
        for sprite in self.sprites:
            screen.blit(sprite.image, sprite.rect)
        pygame.display.flip()
        return None
    
    # Moves the sprites/nanobots one step.
    def moveSprites(self,sprites,objects,goals):
        for goal in goals:
            sprite = sprites[goals.index(goal)]
            object = objects[goal]
            if sprite.rect.centerx != object.rect.centerx:
                movex = (-self.velocity*(abs(sprite.rect.centerx-object.rect.centerx)/float(sprite.rect.centerx-object.rect.centerx)))
            else:
                movex = 0
            if sprite.rect.centery != object.rect.centery:
                movey = (-self.velocity*(abs(sprite.rect.centery-object.rect.centery)/float(sprite.rect.centery-object.rect.centery)))
            else:
                movey = 0
            speed = (movex,movey)
            sprite.rect = sprite.rect.move(speed)
            if sprite.rect.left < 0 or sprite.rect.right > self.width or sprite.rect.top < 0 or sprite.rect.bottom > self.height or len(sprite.rect.collidelistall(self.sprites)) > 1:
                speed = map(lambda x: -x, speed)
                sprite.rect=sprite.rect.move(speed)
        return sprites